/**
 * FileFind - ftp/shares indexing and search php engine
 * Module: common
 * Description: Common classes
 * Copyright (c) 2003-2010 Rage Steel, www.gt2.ru
 */
package ru.ffind.common.model;

import ru.ffind.common.model.Filename;
import ru.ffind.common.model.Entry;
import ru.ffind.common.model.Directory;
import java.util.Date;

/**
 * Base implementation for Entry descendants.
 *
 * @author Rage Steel
 */
public abstract class AbstractEntry implements Entry {

	/* (non-Javadoc)
	 * @see ru.ffind.agent.model.Entry#getAbsPath(java.lang.String)
	 */
	@Override
	public final String getAbsPath(String parentAbsPath) {
		return ("/".equals(parentAbsPath) ? "" : parentAbsPath) + "/" + getName();
	}

	private static boolean entryDatetimeEquals(Entry entry1, Entry entry2) {
		if (!entryNameEquals(entry1, entry2)) {
			return false;
		}
		Date datetime1 = entry1.getDatetime();
		Date datetime2 = entry2.getDatetime();
		if (datetime1 == null) {
			if (datetime2 != null) {
				return false;
			}
		} else if (!datetime1.equals(datetime2)) {
			return false;
		}
		
		return true;
	}	
	
	private static boolean fileEquals(Filename file1, Entry entry2) {
		if (!(entry2 instanceof Filename)) {
			return false;
		}

		if (!entryDatetimeEquals(file1, entry2)) {
			return false;
		}
		
		Filename file2 = (Filename)entry2;
		if (file1.getFileSize() != file2.getFileSize()) {
			return false;
		}
		
		return true;
	}
	
	private static boolean dirEquals(Directory dir1, Entry entry2) {
		if (!(entry2 instanceof Directory)) {
			return false;
		}
		
		if (!entryDatetimeEquals(dir1, entry2)) {
			return false;
		}
		
		return true;
	}
	
	private static boolean entryNameEquals(Entry entry1, Entry entry2) {
		String name1 = entry1.getName();
		String name2 = entry2.getName();
		
		if (name1 == null) {
			if (name2 != null) {
				return false;
			}
		} else if (!name1.equals(name2)) {
			return false;
		}
	
		return true;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj2) {
		if (this == obj2) {
			return true;
		}
		if (null == obj2) {
			return false;
		}
		if (!(obj2 instanceof Entry)) {
			return false;
		}
		
		return entryNameEquals(this, (Entry)obj2);
	}


	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		String name = getName();
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	
	/* (non-Javadoc)
	 * @see ru.ffind.agent.model.Entry#equalsMetadata(ru.ffind.agent.model.Entry)
	 */
	@Override
	public boolean equalsMetadata(Entry entry) {
		if (!equals(entry)) {
			return false;
		}
		if (this instanceof Filename) {
			return fileEquals((Filename)this, entry);
		} else if (this instanceof Directory) {
			return dirEquals((Directory)this, entry);
		}
		throw new IllegalArgumentException("Unknown entry class: " + entry.getClass());
	}
}
